package com.example.mybatisplus.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.example.mybatisplus.mapper.StockMapper;
import com.example.mybatisplus.params.StockParam;
import com.example.mybatisplus.pojo.ResponseVo;
import com.example.mybatisplus.pojo.StockInfo;
import com.example.mybatisplus.service.StockService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
public class StockServiceImpl extends ServiceImpl<StockMapper, StockInfo> implements StockService {

    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Override
    public ResponseVo saveOne(StockInfo stockInfo) {
        log.info("invoke StockServiceImpl#saveOne method start --------");
        log.info("stockInfo={}", JSON.toJSON(stockInfo));
        setCreatedByAndCreatedByDate(stockInfo);
        setLastUpdatedByAndLastUpdatedDate(stockInfo);
        boolean result = super.save(stockInfo);
        ResponseVo responseVo;
        if (result) {
            responseVo = ResponseVo.success(result);
        } else {
            responseVo = ResponseVo.error("保存失败");
        }
        return responseVo;
    }

    @Override
    public ResponseVo saveBatch(List<StockInfo> stockInfoList) {
        log.info("invoke StockServiceImpl#saveBatch method start --------");
        log.info("stockInfoList={}", JSON.toJSON(stockInfoList));
        for (StockInfo stockInfo : stockInfoList) {
            setCreatedByAndCreatedByDate(stockInfo);
            setLastUpdatedByAndLastUpdatedDate(stockInfo);
        }
        boolean result = super.saveBatch(stockInfoList);
        ResponseVo responseVo;
        if (result) {
            responseVo = ResponseVo.success(result);
        } else {
            responseVo = ResponseVo.error("批量保存失败");
        }
        return responseVo;
    }

    @Override
    public ResponseVo updateOne(StockInfo stockInfo) {
        log.info("invoke StockServiceImpl#updateOne method start --------");
        log.info("stockInfo={}", JSON.toJSON(stockInfo));
        setLastUpdatedByAndLastUpdatedDate(stockInfo);
        boolean result = super.updateById(stockInfo);
        ResponseVo responseVo;
        if (result) {
            responseVo = ResponseVo.success(result);
        } else {
            responseVo = ResponseVo.error("更新失败");
        }
        return responseVo;
    }

    @Override
    public ResponseVo updateBatch(List<StockInfo> stockInfoList) {
        log.info("invoke StockServiceImpl#updateBatch method start --------");
        log.info("stockInfoList={}", JSON.toJSON(stockInfoList));
        for (StockInfo stockInfo : stockInfoList) {
            setLastUpdatedByAndLastUpdatedDate(stockInfo);
        }
        boolean result = super.updateBatchById(stockInfoList);
        ResponseVo responseVo;
        if (result) {
            responseVo = ResponseVo.success(result);
        } else {
            responseVo = ResponseVo.error("批量更新失败");
        }
        return responseVo;
    }

    @Override
    public ResponseVo findPageByCondition(StockParam stockParam, int pageNo, int pageSize) {
        log.info("invoke StockServiceImpl#findPageByCondition method start --------");
        log.info("pageNo={}, pageSize={}", pageNo, pageSize);
        if (pageNo <= 0) {
           pageNo = 1;
        }
        if (pageSize <= 10) {
            pageSize = 10;
        }
        if (pageSize > 500) {
            pageSize = 500;
        }
        IPage<StockInfo> pageParam = new Page<>(pageNo, pageSize);
        QueryWrapper<StockInfo> queryWrapper = getQueryWrapperByParam(stockParam);
        IPage<StockInfo> pageData = super.page(pageParam, queryWrapper);
        ResponseVo responseVo = ResponseVo.success(pageData);
        return responseVo;
    }

    @Override
    public ResponseVo findCountByGoodCode(String goodCode) {
        log.info("invoke StockServiceImpl#findCountByGoodCode method start --------");
        log.info("goodCode={}", goodCode);
        ResponseVo responseVo;
        if (StringUtils.isEmpty(goodCode)) {
            responseVo = ResponseVo.error(HttpStatus.BAD_REQUEST.value(), "goodCode cannot be null");
            return responseVo;
        }
        Integer count = this.baseMapper.findCountByGoodCode(goodCode);
        if (count == 1) {
            responseVo = ResponseVo.success(count);
        } else {
            responseVo = ResponseVo.error("更新库存失败");
        }
        return responseVo;
    }

    @Override
    public ResponseVo updateStockCountById(Long id, Integer count) {
        log.info("invoke StockServiceImpl#updateStockCountById method start --------");
        ResponseVo responseVo;
        if (id == null || id < 1) {
            responseVo = ResponseVo.error(HttpStatus.BAD_REQUEST.value(), "invalid request param of id");
            return responseVo;
        }
        if (count == null || count < 1) {
            responseVo = ResponseVo.error(HttpStatus.BAD_REQUEST.value(), "invalid request param of count");
            return responseVo;
        }
        Integer resultCount = this.baseMapper.updateStockById(id, count);
        if (resultCount == 1) {
            responseVo = ResponseVo.success(resultCount);
        } else {
            responseVo = ResponseVo.error("更新商品库存失败");
        }
        return responseVo;
    }

    /**
     * 设置创建人与创建时间
     *
     * @param stockInfo
     */
    private void setCreatedByAndCreatedByDate(StockInfo stockInfo) {
        if (StringUtils.isEmpty(stockInfo.getCreatedBy())){
            stockInfo.setCreatedBy("system");
        }
        if (stockInfo.getCreatedDate() == null) {
            stockInfo.setCreatedDate(DateUtil.date(System.currentTimeMillis()));
        }
    }

    /**
     * 设置最后修改人与最后修改时间
     *
     * @param stockInfo
     */
    private void setLastUpdatedByAndLastUpdatedDate(StockInfo stockInfo) {
        if (StringUtils.isEmpty(stockInfo.getLastUpdatedBy())){
            stockInfo.setLastUpdatedBy("system");
        }
        if (stockInfo.getLastUpdatedDate() == null) {
            stockInfo.setLastUpdatedDate(DateUtil.date(System.currentTimeMillis()));
        }
    }

    /**
     * 处理动态查询
     *
     * @param stockParam
     * @return queryWrapper
     */
    private QueryWrapper<StockInfo> getQueryWrapperByParam(StockParam stockParam) {
        QueryWrapper<StockInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "good_code", "good_name", "unit_price", "count",
                "created_date", "created_by", "last_updated_by", "last_updated_date");
        // 注意加了唯一索引的列使用like查询会导致查不出结果
        queryWrapper.eq(!StringUtils.isEmpty(stockParam.getGoodCode()), "good_code", stockParam.getGoodCode());

        queryWrapper.likeRight(!StringUtils.isEmpty(stockParam.getGoodName()), "good_name", stockParam.getGoodName());

        queryWrapper.eq(stockParam.getCount() != null, "count", stockParam.getCount());

        queryWrapper.ge(stockParam.getQueryMinUnitPrice() != null,"unit_price", stockParam.getQueryMinUnitPrice());

        queryWrapper.le(stockParam.getQueryMaxUnitPrice() != null,"unit_price", stockParam.getQueryMaxUnitPrice());

        queryWrapper.eq(StringUtils.isNotBlank(stockParam.getCreatedBy()), "created_by", stockParam.getCreatedBy());

        if (!StringUtils.isEmpty(stockParam.getQueryMinCreatedDate())) {
            DateTime queryMinCreatedDate = DateUtil.parse(stockParam.getQueryMinCreatedDate(), DATE_TIME_FORMAT);
            queryWrapper.ge("created_date", queryMinCreatedDate);
        }
        if (!StringUtils.isEmpty(stockParam.getQueryMaxCreatedDate())) {
            DateTime queryMaxCreatedDate = DateUtil.parse(stockParam.getQueryMaxCreatedDate(), DATE_TIME_FORMAT);
            queryWrapper.le("created_date", queryMaxCreatedDate);
        }
        if (!StringUtils.isEmpty(stockParam.getLastUpdatedBy())) {
            queryWrapper.eq(StringUtils.isNotBlank(stockParam.getLastUpdatedBy()), "last_updated_by", stockParam.getLastUpdatedBy());
        }
        if (!StringUtils.isEmpty(stockParam.getQueryMinUpdateDate())) {
            DateTime queryMinUpdateDate = DateUtil.parse(stockParam.getQueryMinUpdateDate(), DATE_TIME_FORMAT);
            queryWrapper.ge("last_updated_date", queryMinUpdateDate);
        }
        if (!StringUtils.isEmpty(stockParam.getQueryMaxUpdateDate())) {
            DateTime queryMaxUpdateDate = DateUtil.parse(stockParam.getQueryMaxUpdateDate(), DATE_TIME_FORMAT);
            queryWrapper.le("last_updated_date", queryMaxUpdateDate);
        }
        queryWrapper.orderByAsc("id");
        return queryWrapper;
    }
}
